#include <iomanip.h>
#include <math.h>

#include "atom.h"
		
atom::atom(){ }

atom::atom( char aLabel, double a = 0, double b = 0, double c = 0 ) { x = a; y = b; z = c; label = aLabel; }

atom::atom( const atom& rhs ) {
	x = rhs.x; 
	y = rhs.y; 
	z = rhs.z; 
	label = rhs.label;
}

atom::~atom() {}

atom& atom::operator=( const atom &rhs ) {
	x = rhs.x;
	y = rhs.y;
	z = rhs.z;
	label = rhs.label;
			
	return *this;
}
	
double atom::operator[]( int index ) {
	
	if(index==0) return x;
	if(index==1) return y;
	if(index==2) return z;
	else {
		cout << "Accessing wrong index." << endl;
		exit(1);
	}

}

	
double atom::getDistanceTo( atom &rhs ) {
	return sqrt( pow( x - rhs.x, 2.0 ) + pow( y - rhs.y, 2.0 ) + pow( z - rhs.z, 2.0 ) );
}
		
atom& atom::operator+( atom &rhs ) {
	x = x + rhs.x;
	y = y + rhs.y;
	z = z + rhs.z;
	
	return *this;
}
		
atom& atom::operator+=( atom &rhs ) {
	x = x + rhs.x;
	y = y + rhs.y;
	z = z + rhs.z;
			
	return *this;
}		
		
atom& atom::operator-( atom &rhs ) {
	x = x - rhs.x;
	y = y - rhs.y;
	z = z - rhs.z;
			
	return *this;
}	

atom& atom::operator-=( atom &rhs ) {
	x = x - rhs.x;
	y = y - rhs.y;
	z = z - rhs.z;
			
	return *this;
}			
	
void atom::setAt( int index, double value ) {

	if( index==0 ) x = value;
	else if( index==1 ) y = value;
	else if( index==2 ) z = value;
	else {
		cout << "Invalid atom axis" << endl;
		exit(1);
	}

}
	
void atom::printToFileStream( ofstream& out ) {
	
	out << scientific << setprecision( PRECISION );
	out << label << " " << x << " " << y << " " << z << endl;
	
}

ostream& operator<<( ostream& out, const atom& anAtom ) {

	out << scientific << setprecision( PRECISION );
	out << anAtom.label << " " << anAtom.x << " " << anAtom.y << " " << anAtom.z << endl;
	return out;

}		

